

<!DOCTYPE html>
<html lang="en" data-default-color-scheme=&#34;auto&#34;>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/favicon.png">
  <link rel="icon" type="image/png" href="/img/favicon.png">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="description" content="懂哥的博客">
  <meta name="author" content="John Doe">
  <meta name="keywords" content="">
  <title>Java - 闪肆的小屋</title>

  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" />


  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@4.0.0/github-markdown.min.css" />
  <link  rel="stylesheet" href="/lib/hint/hint.min.css" />

  
    
    
      
      <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@10.4.0/styles/github-gist.min.css" />
    
  

  
    <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css" />
  



<!-- 主题依赖的图标库，不要自行修改 -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_ba1fz6golrf.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_kmeydafke9r.css">


<link  rel="stylesheet" href="/css/main.css" />

<!-- 自定义样式保持在最底部 -->


  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    var CONFIG = {"hostname":"example.com","root":"/","version":"1.8.7","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"right","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"copy_btn":true,"image_zoom":{"enable":true},"toc":{"enable":true,"headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"onlypost":false},"web_analytics":{"enable":false,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null}}};
  </script>
  <script  src="/js/utils.js" ></script>
  <script  src="/js/color-schema.js" ></script>
<meta name="generator" content="Hexo 5.3.0"></head>


<body>
  <header style="height: 70vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand"
       href="/">&nbsp;<strong>Homie</strong>&nbsp;</a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                Home
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/archives/">
                <i class="iconfont icon-archive-fill"></i>
                Archives
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/">
                <i class="iconfont icon-category-fill"></i>
                Categories
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                Tags
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                联系我
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" data-toggle="modal" data-target="#modalSearch">&nbsp;<i
                class="iconfont icon-search"></i>&nbsp;</a>
          </li>
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" href="javascript:">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="banner" id="banner" parallax=true
         style="background: url('/img/default.png') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="page-header text-center fade-in-up">
            <span class="h2" id="subtitle" title="Java">
              
            </span>

            
              <div class="mt-3">
  
  
    <span class="post-meta">
      <i class="iconfont icon-date-fill" aria-hidden="true"></i>
      <time datetime="2021-03-05 17:18" pubdate>
        March 5, 2021 pm
      </time>
    </span>
  
</div>

<div class="mt-1">
  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      2.4k 字
    </span>
  

  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      26
       分钟
    </span>
  

  
  
</div>

            
          </div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div class="py-5" id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">Java</h1>
            
            <div class="markdown-body">
              <h3 id="Java学习笔记"><a href="#Java学习笔记" class="headerlink" title="Java学习笔记"></a>Java学习笔记</h3><hr>
<p><img src="https://img-blog.csdnimg.cn/20210128144929441.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MTI4MTE4Mw==,size_16,color_FFFFFF,t_70#pic_center" srcset="/img/loading.gif"></p>
<h1 id="1-关于传值"><a href="#1-关于传值" class="headerlink" title="1. 关于传值"></a>1. 关于传值</h1><hr>
<p>Java 中只有<strong>值传递</strong>, 我就把除了基本类型外所有的变量都当成<strong>指针</strong>,然后他们指向真正的对象就好</p>
<h1 id="2-开放的访问属性-见-Display-项目"><a href="#2-开放的访问属性-见-Display-项目" class="headerlink" title="2. 开放的访问属性(见 Display 项目)"></a>2. 开放的访问属性(见 Display 项目)</h1><hr>
<ul>
<li><p>public 意味着任何人都可以自由地使用</p>
</li>
<li><p>如果一个函数前没有加 public 限定，意味着和他位于<strong>同一个包</strong>的类可以访问，称为 friendly</p>
</li>
<li><p>protected</p>
</li>
<li><p>public Class 意味着任何人都可以用这个类来定义变量<br>要求：public Class 必须定义在同名源文件中<br>一个 .java 文件为一个编译单元，<strong>一个编译单元只能有一个 public 的类</strong></p>
</li>
</ul>
<h1 id="3-类变量和类函数"><a href="#3-类变量和类函数" class="headerlink" title="3. 类变量和类函数"></a>3. 类变量和类函数</h1><hr>
<p><img src="https://img-blog.csdnimg.cn/20210128143141132.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MTI4MTE4Mw==,size_16,color_FFFFFF,t_70#pic_center" srcset="/img/loading.gif"></p>
<p>在 ClassA 中有一个 static 类型的变量，它不属于 ClassA 创建的任何对象，而是属于 ClassA 本身。可以通过 <code>ClassA.value</code> 或者<code>a.value</code>来使用。<code>a.value</code>与<code>b.value</code>实际上是同一个变量。</p>
<p><code>f()</code>就是一个类函数，可以直接调用，但<code>f()</code>内部<strong>只能访问静态成员</strong>。</p>
<p>ArrayList 可以实现一个可变的数组，与 C++ 中的 Vector 容器类似，内置了增加/插入<code>add()</code>、删除<code>remove()</code>等方法。</p>
<h1 id="4-对象数组"><a href="#4-对象数组" class="headerlink" title="4. 对象数组"></a>4. 对象数组</h1><hr>
<p>对象数组与基础类型的数组如<code>int []</code>是不同的。对象数组的每个元素都是对象的<strong>管理者</strong>，而非对象的本身。</p>
<p><img src="https://img-blog.csdnimg.cn/20210128143408611.jpg#pic_center" srcset="/img/loading.gif"></p>
<p>当通过创建了一个<code>String</code>类型的数组时，这个数组的每一个“格子”里都是<code>String</code>类型的<strong>管理者</strong>。此时该数组每一个元素管理的都是空的，即<code>null</code>。</p>
<p>因此，需要给它每一个元素创建对象，如：</p>
<p><img src="https://img-blog.csdnimg.cn/20210128143534583.jpg#pic_center" srcset="/img/loading.gif"></p>
<h2 id="对象数组的-for-each-循环"><a href="#对象数组的-for-each-循环" class="headerlink" title="对象数组的 for-each 循环"></a>对象数组的 for-each 循环</h2><p><img src="https://img-blog.csdnimg.cn/20210128143642286.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MTI4MTE4Mw==,size_16,color_FFFFFF,t_70#pic_center" srcset="/img/loading.gif"></p>
<p>输出结果为：</p>
<p><img src="https://img-blog.csdnimg.cn/20210128143803372.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MTI4MTE4Mw==,size_16,color_FFFFFF,t_70#pic_center" srcset="/img/loading.gif"></p>
<p>这其中发生的事情是<code>for-each</code>循环中，变量<code>i</code>与a中的元素管理<strong>同一个对象</strong>，所以调用<code>i.set(0)</code>后，遍历<code>a</code>数组得到的结果也是0。</p>
<h1 id="5-容器与泛型"><a href="#5-容器与泛型" class="headerlink" title="5.容器与泛型"></a>5.容器与泛型</h1><hr>
<ul>
<li> 常用Collections</li>
</ul>
<p><img src="https://img-blog.csdnimg.cn/20210226203527612.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MTI4MTE4Mw==,size_16,color_FFFFFF,t_70" srcset="/img/loading.gif"></p>
<h2 id="常用容器"><a href="#常用容器" class="headerlink" title="常用容器"></a>常用容器</h2><ol>
<li><p>ArrayList</p>
<p>类似于 c++ 中 Vector 的存在</p>
</li>
</ol>
<p><img src="https://img-blog.csdnimg.cn/20210226203559344.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MTI4MTE4Mw==,size_16,color_FFFFFF,t_70" srcset="/img/loading.gif"></p>
<ol start="2">
<li><p>集合容器(set)</p>
<p>Hashset</p>
</li>
</ol>
<p><img src="https://img-blog.csdnimg.cn/20210226203642977.jpg" srcset="/img/loading.gif"></p>
<p>   显示结果:</p>
<p><img src="https://img-blog.csdnimg.cn/20210226203806694.jpg" srcset="/img/loading.gif"></p>
<p>​    集合容器<code>HashSet</code>具有<strong>无序性</strong>和<strong>无重复型</strong>。此外，如果一个类的内部实现了<code>String toString()</code>函数(如数组、ArrayList 、HashMap )，那么可以直接用<code>System.out.println(容器名)</code>打印该函数内部指定返回的内容。<br>遍历 HashSet 可以使用迭代器或者 for-each 循环</p>
<p><img src="https://img-blog.csdnimg.cn/20210226203937643.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MTI4MTE4Mw==,size_16,color_FFFFFF,t_70" srcset="/img/loading.gif"></p>
<p>   <strong>HashSet 检查重复的方法 hashCode() 与 equals()</strong></p>
<p>   当把对象加入 HashSet 时，它会首先使用该对象的 hashcode 值u来判断对象加入的位置，但是同时也与其他对象的 hashcode 比对，如果没有相同的，这个对象<strong>一定不是重复的</strong>。如果 hashcode 相等，对象也不一定相等，这就会调用其中一者的 <code>equals()</code> 来判断是否真的相同。</p>
<hr>
<p>   TreeSet</p>
<p>   TreeSet 同样不允许有重复的元素，但是他会一直保持有序。<br>要使用 TreeSet，必须保证下面其中一项为真：</p>
<ul>
<li>TreeSet 中的元素实现了 Comparable</li>
<li>使用重载、取用 Comparable 参数的构造函数来创建 TreeSet</li>
</ul>
<p><img src="https://img-blog.csdnimg.cn/20210226204245779.jpg" srcset="/img/loading.gif"></p>
<p>   哈希表(HashMap)</p>
<p>   哈希表以键值对的形式储存顺序。</p>
<p><img src="https://img-blog.csdnimg.cn/20210226204356717.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MTI4MTE4Mw==,size_16,color_FFFFFF,t_70" srcset="/img/loading.gif"></p>
<p>遍历哈希表中的值可以用以下方法：</p>
<p><img src="https://img-blog.csdnimg.cn/20210226204245779.jpg" srcset="/img/loading.gif"></p>
<p>打印结果</p>
<p><img src="https://img-blog.csdnimg.cn/20210226204356717.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MTI4MTE4Mw==,size_16,color_FFFFFF,t_70" srcset="/img/loading.gif"></p>
<p>没有打印出 “half-dollar” , 这是因为 HashMap 中键( Key )是<strong>不允许重复</strong>的，所以后一次的 “五毛” 会覆盖前一次。</p>
<hr>
<h2 id="由-sort-方法所知道的"><a href="#由-sort-方法所知道的" class="headerlink" title="由 sort() 方法所知道的"></a>由 sort() 方法所知道的</h2><p>ArrayList 类中不含 <code>sort()</code> 函数, 但是 Collections 类中含有 <code>sort()</code>方法, 所以可以使用<code>Collections.sort(List list)</code>将实现了 List 接口的 ArrayList 传进去.</p>
<p><img src="https://img-blog.csdnimg.cn/20210305173941814.jpg#pic_center" srcset="/img/loading.gif"></p>
<p>但当 ArrayList 中存放的不是 String 而是一个自定义的对象时, 就不能直接用了.如下面的代码不能通过编译:</p>
<p><img src="https://img-blog.csdnimg.cn/20210305174025421.jpg#pic_center" srcset="/img/loading.gif"></p>
<p>以下两种都是正确的:</p>
<p><img src="https://img-blog.csdnimg.cn/20210305174133127.jpg#pic_center" srcset="/img/loading.gif"></p>
<p>这两者<strong>不同</strong>. 前者表示任何 Animal 或者 Animal 的子类都可以被传入, 后者仅能接收ArrayLiast &lt; Animal &gt;</p>
<hr>
<p><code>sort()</code>函数的声明如下:</p>
<p><img src="https://img-blog.csdnimg.cn/20210305174222434.jpg#pic_center" srcset="/img/loading.gif"></p>
<p>由此可知, T 必须实现( 此处也是 extends ) Comparable 这个接口.<code>? super T</code>代表 Comparable 的类型参数必须是 T 或者 T 的父型.<br>所以 Song 类应该是这样的:</p>
<p><img src="https://img-blog.csdnimg.cn/20210305174310928.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MTI4MTE4Mw==,size_16,color_FFFFFF,t_70#pic_center" srcset="/img/loading.gif"></p>
<p>comepareTo 返回值小于 0, 则传入的 Song 大于执行的 Song.</p>
<hr>
<p>除了实现 Comparable, 还可以用 Comparator 参数来调用不同方式的排序.</p>
<p><img src="https://img-blog.csdnimg.cn/20210305174401270.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MTI4MTE4Mw==,size_16,color_FFFFFF,t_70#pic_center" srcset="/img/loading.gif"></p>
<p>于是, 可以在其他地方调用两个参数版本的<code>sort()</code>:</p>
<h1 id="6-继承-以实现一个存放-CD-、DVD-的-Database-为例"><a href="#6-继承-以实现一个存放-CD-、DVD-的-Database-为例" class="headerlink" title="6.继承(以实现一个存放 CD 、DVD 的 Database 为例)"></a>6.继承(以实现一个存放 CD 、DVD 的 Database 为例)</h1><hr>
<p>在 Database.java 文件中实现了一个 Database 的类，其中含有 ArrayList 类型的成员变量 list 来存放数据。此外还有对 list 进行增添和遍历的<code>add(Item newItem)</code>和<code>list()</code>方法。</p>
<p><img src="https://img-blog.csdnimg.cn/20210305174547387.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MTI4MTE4Mw==,size_16,color_FFFFFF,t_70#pic_center" srcset="/img/loading.gif"></p>
<p>Item 作为父类，仅含有最基础的成员变量和成员函数。</p>
<p><img src="https://img-blog.csdnimg.cn/20210305174641730.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MTI4MTE4Mw==,size_16,color_FFFFFF,t_70#pic_center" srcset="/img/loading.gif"></p>
<p>CD 是由 Item 派生的一个类，在 Item 基础上增添了很多属性，并且重写了<code>print()</code>方法。在 Database 类中调用<code>item.print()</code>方法时，若子类重写了该方法，只会调用子类中的。</p>
<p><img src="https://img-blog.csdnimg.cn/20210305174722958.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MTI4MTE4Mw==,size_16,color_FFFFFF,t_70#pic_center" srcset="/img/loading.gif"></p>
<h2 id="子类继承了什么"><a href="#子类继承了什么" class="headerlink" title="子类继承了什么"></a>子类继承了什么</h2><p>父类中 <strong>private</strong> 属性的<strong>只有自己</strong>可以访问，<strong>protected</strong> 属性的还可供<strong>子类和同一个包内的其他类访问</strong>。</p>
<p>对于父类中的变量，可以通过将其设为 protected 从而在子类的构造器中对其进行初始化，然而更好的方法是变量属于哪一个类，就用哪一个类的构造器初始化，此时可以借助子类的<code>super()</code>方法传递给父类构造器。初始化的顺序为：1. 父类构造（若子类中未给<code>super()</code>参数或者未调用<code>super()</code>，则自动调用父类默认构造器；若给了<code>super()</code>参数，调用父类对应的构造器）； 2. 定义初始化； 3. 子类构造。</p>
<h2 id="子类和父类复杂的关系"><a href="#子类和父类复杂的关系" class="headerlink" title="子类和父类复杂的关系"></a>子类和父类复杂的关系</h2><p>若子类与父类含有同名的成员变量，在子类中父类的变量会被隐藏。而父类的函数中处理的还是父类的变量。使用<code>super.f()</code>可以<strong>调用父类中的<code>f()</code>函数</strong>。</p>
<p><strong>重写</strong>（ Override ）不同于重载（ Overload ），它是父类中某个方法的重新实现而不是拓展。在重写的方法之前加上 <code>@Override</code>可以让编译器帮助检查。</p>
<h1 id="子类和子类型"><a href="#子类和子类型" class="headerlink" title="子类和子类型"></a>子类和子类型</h1><ul>
<li><p>类定义了类型</p>
</li>
<li><p>子类定义了子类型</p>
</li>
<li><p>子类的对象可以被<strong>当作父类的对象</strong>来使用</p>
<p>赋值给父类的变量</p>
<p>传递给需要父类对象的函数</p>
<p>放进存放父类对象的容器里</p>
</li>
</ul>
<h1 id="多态变量"><a href="#多态变量" class="headerlink" title="多态变量"></a>多态变量</h1><ul>
<li>Java 的对象变量是<strong>多态</strong>的，它们能保存不止一种类型的对象</li>
<li>它们可以保存的是声明类型的对象，或声明类型的子类的对象</li>
<li>当把子类的对象赋给父类的变量的时候，就发生了<strong>向上造型</strong>，发生向上造型之后，尽管变量是父类类型的，但调用的仍然是子类的方法（如上述存放 Item 类型容器进行 for-each 循环，并调用 <code>print()</code> 方法时，调用的是子类中重写的方法而非父类的方法）。<br>注：向下造型并非任何时候都不可行，唯一可行的情况是父类型变量实际管理的对象是该子类型的。</li>
<li>若函数需要一个 Animal 类型参数的 ArrayList，那么只能传入 <code>ArrayList&lt;Animal&gt;</code>而不能是<code>ArrayList&lt;Dog&gt;</code>，否则就只能把函数的声明改为</li>
</ul>
<p><img src="https://img-blog.csdnimg.cn/20210305175216649.jpg#pic_center" srcset="/img/loading.gif"></p>
<p>​        或者</p>
<p><img src="https://img-blog.csdnimg.cn/20210305175241837.jpg#pic_center" srcset="/img/loading.gif"></p>
<p>​        注：C++ 实现这个很复杂，可以用 C++ 20 的新内容实现：</p>
<p><img src="https://img-blog.csdnimg.cn/2021030517530859.jpg#pic_center" srcset="/img/loading.gif"></p>
<h1 id="Object类"><a href="#Object类" class="headerlink" title="Object类"></a>Object类</h1><hr>
<p>几乎在所有的 oop 语言中，都有一个“<strong>根</strong>”的存在。在 Java 中，这个“根”就是 <strong>Object</strong> 类。<br>Object 类中包含有：</p>
<ul>
<li>toString()</li>
<li>equals()</li>
</ul>
<p>两个方法，前者可以打印对象的信息（可以在子类中具体实现）；后者<strong>判断是否管理着同一个对象</strong>。如果要实现判断内容是否一致，需要在子类中实现。比如，要实现只要 CD 类中 artist 成员相同，<code>equals()</code>就返回 true，需要这样写：</p>
<p><img src="https://img-blog.csdnimg.cn/20210305175449154.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MTI4MTE4Mw==,size_16,color_FFFFFF,t_70#pic_center" srcset="/img/loading.gif"></p>
<h1 id="以“城堡游戏”为例改良代码-详见源代码"><a href="#以“城堡游戏”为例改良代码-详见源代码" class="headerlink" title="以“城堡游戏”为例改良代码(详见源代码)"></a>以“城堡游戏”为例改良代码(详见源代码)</h1><hr>
<h2 id="消除代码复制"><a href="#消除代码复制" class="headerlink" title="消除代码复制"></a>消除代码复制</h2><p>在原来的代码中，至少两处用到了相同的提示信息，需要将提示信息放在一个函数 <code>showPrompt()</code> 中来减少重复代码。</p>
<h2 id="封装"><a href="#封装" class="headerlink" title="封装"></a>封装</h2><p>封装以降低耦合度。在原来的代码中，Game 类大量使用了 Room 类中的成员，比如得到 currentRoom 的出口，正确的做法是在 Room 类中的 <code>getExits()</code> 以 String 返回出口，而非返回 Room 类的对象；Game 类中 <code>goRoom()</code> 函数也不应该直接操作 Room 类的成员，而应让 Room 类自己返回输入所对应的房间。</p>
<h2 id="可拓展性"><a href="#可拓展性" class="headerlink" title="可拓展性"></a>可拓展性</h2><p>在原来的代码中, Room 类中含有 4 个表示出口的 Room 类型对象, 这不是好的做法, 因为这样大大降低了代码的可拓展性, 如果要增加 “up” 或者 “down” 方向的出口, 就会变得十分复杂. 更好的方式是用容器来增加代码的灵活性. 改造后, 只需在 <code>createRoom()</code>中写<code>outside().setExit(&quot;up&quot;, anotherRoom);</code>便可以使 outside 这个房间的 up 方向是 anotherRoom.</p>
<p><strong>增加可扩展性:框架+数据</strong></p>
<ul>
<li>命令的解析<strong>脱离 if-else</strong></li>
<li>定义一个 Handler 来处理命令</li>
<li>用 Hash 表来保存命令和 Handler 之间的关系</li>
</ul>
<p>未完待续 持续更新  持续学习</p>
<blockquote>
<p><strong>欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论，也可以邮件至 <a href="mailto:&#x37;&#54;&#49;&#x37;&#x34;&#x36;&#50;&#x32;&#x39;&#x40;&#113;&#113;&#46;&#x63;&#x6f;&#109;">&#x37;&#54;&#49;&#x37;&#x34;&#x36;&#50;&#x32;&#x39;&#x40;&#113;&#113;&#46;&#x63;&#x6f;&#109;</a></strong></p>
</blockquote>

            </div>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                
                  <div class="post-meta">
                    <i class="iconfont icon-tags"></i>
                    
                      <a class="hover-with-bg" href="/tags/Java%E7%AC%94%E8%AE%B0/">Java笔记</a>
                    
                  </div>
                
              </div>
              
                <p class="note note-warning">本博客所有文章除特别声明外，均采用 <a target="_blank" href="https://creativecommons.org/licenses/by-sa/4.0/deed.zh" rel="nofollow noopener noopener">CC BY-SA 4.0 协议</a> ，转载请注明出处！</p>
              
              
                <div class="post-prevnext">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/2021/05/31/Spring5%E8%AF%BE%E5%A0%82%E7%AC%94%E8%AE%B0/">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">Spring5</span>
                        <span class="visible-mobile">Previous</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/2021/02/05/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92/">
                        <span class="hidden-mobile">动态规划</span>
                        <span class="visible-mobile">Next</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;TOC</p>
  <div class="toc-body" id="toc-body"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    

    
      <a id="scroll-top-button" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">Search</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">keyword</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
    

    
  </main>

  <footer class="text-center mt-5 py-3">
  <div class="footer-content">
     <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
  </div>
  

  

  
</footer>

<!-- SCRIPTS -->

  <script  src="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js" ></script>
<script  src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js" ></script>
<script  src="/js/debouncer.js" ></script>
<script  src="/js/events.js" ></script>
<script  src="/js/plugins.js" ></script>

<!-- Plugins -->


  
    <script  src="/js/lazyload.js" ></script>
  



  



  <script  src="https://cdn.jsdelivr.net/npm/tocbot@4.12.0/dist/tocbot.min.js" ></script>



  <script  src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js" ></script>



  <script  src="https://cdn.jsdelivr.net/npm/anchor-js@4.3.0/anchor.min.js" ></script>



  <script defer src="https://cdn.jsdelivr.net/npm/clipboard@2.0.6/dist/clipboard.min.js" ></script>






  <script  src="https://cdn.jsdelivr.net/npm/typed.js@2.0.11/lib/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var title = document.getElementById('subtitle').title;
      
      typing(title)
      
    })(window, document);
  </script>



  <script  src="/js/local-search.js" ></script>
  <script>
    (function () {
      var path = "/local-search.xml";
      var inputArea = document.querySelector("#local-search-input");
      inputArea.onclick = function () {
        searchFunc(path, 'local-search-input', 'local-search-result');
        this.onclick = null
      }
    })()
  </script>















<!-- 主题的启动项 保持在最底部 -->
<script  src="/js/boot.js" ></script>



</body>
</html>
